home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Mousetools / MenuStay / MenuStay.ez < prev    next >
Text File  |  1996-09-26  |  16KB  |  737 lines

  1. *--------------------------------------------------------------------------
  2.  
  3. *                   MenuStay V1.0
  4.  
  5.  
  6. ;                is FreeWare
  7.  
  8. ;      With this small tool it's now possible to go around the menus
  9. ;          without holding the right mouse button.
  10. ; Just press AND release the right mouse button over the wished menubar.
  11.  
  12. ;            In the menu-stay-mode it's possible
  13. ;          to add a command to items that don't have one,
  14. ;            by pressing the left mouse button.
  15.  
  16. ;              To activate the screen blanker
  17. ;    just press and release the cursor up and down keys simultaneous.
  18.  
  19.  
  20. ;     Once installed, this tool only uses 568 bytes of memory.
  21. ;        To get back to normal simply run the program again.
  22.  
  23. ;       No need to 'RUN' or 'RUNBACK' this tool from the CLI.
  24.  
  25. ;            1993  by Alexandros Loghis
  26.  
  27. *             Sun Apr 18 21:25:19 1993
  28.  
  29.                    ;:-)
  30.  
  31.  
  32. *          Some information about this source code
  33.  
  34. ;               All routines where taken from
  35. ;     Preben Nielsen's RMBShift V1.0 assembly source (thanks),
  36. ;        exept the input handler that was written by myself.
  37.  
  38. ;           The whole program was (re)written in
  39. ;          Joe Siebenmann's EZAsm V1.6 (Fish 592).
  40. ;         Assembled with Charlie Gibbs A68k V2.71.
  41.  
  42. ;  EZAsm combines parts of "C" with 68000 assembly, giving it the "feel"
  43. ;            of a higher level language.
  44. ;       The resulting code is optimized as much as possible.
  45.  
  46. *--------------------------------------------------------------------------
  47.  
  48.     include "exec/io.i"
  49.     include "exec/memory.i"
  50.     include "exec/interrupts.i"
  51.     include "devices/input.i"
  52.     include "devices/inputevent.i"
  53.     include "libraries/dosextens.i"
  54.  
  55.     include "hardware/custom.i"
  56.     include "hardware/dmabits.i"
  57.     include "intuition/intuitionbase.i"
  58.     include "intuition/intuition.i"
  59.  
  60. *--------------------------------------------------------------------------
  61.  
  62. LONG    _DosBase WBMsg PProcess HMem
  63.  
  64. *--------------------------------------------------------------------------
  65.  
  66. Main    PProcess = FindTask( 0 )
  67.     a2     = d0
  68.     pr_CLI(a2) = 0 l {
  69.       WaitPort( &pr_MsgPort(a2) )        ;WBStart
  70.       WBMsg = GetMsg( &pr_MsgPort(a2) )
  71.     }
  72.  
  73.     _DosBase = OldOpenLibrary( &DosName(pc) )
  74.     beq.s    Error
  75.     lea    IntBase(pc),a2
  76.     (a2)    = OldOpenLibrary( &IntName(pc) )
  77.     beq.s    Error
  78.  
  79.     lea    IHSName(pc),a1
  80.     bsr    FindThisPort
  81.     beq.s    DoInstall
  82.  
  83. DoRemove
  84.     CloseLibrary( IntBase(pc) )
  85.     moveq    #REMOVED,d7        because of the forward reference
  86.     lea    IHS(pc),a0
  87.     lea    PSEndIHS1(pc),a1
  88.     lea    PSEndIHS2(pc),a2
  89.     bsr    RemoveHandler
  90.     beq.s    ShowMsg
  91.     moveq    #CANTREMOVE,d7
  92.     bra.s    ShowMsg
  93.  
  94. DoInstall
  95.     moveq    #INSTALLED,d7
  96.     lea    IHS(pc),a0
  97.     lea    PSPrepIHS1(pc),a1
  98.     lea    PSPrepIHS2(pc),a2
  99.     bsr    InstallHandler
  100.     beq.s    ShowMsg
  101.     moveq    #CANTINSTALL,d7
  102. ShowMsg d0 = d7 l
  103.     bsr.s    CONMsg
  104.  
  105. Error    _DosBase != 0 {
  106.       CloseLibrary( _DosBase )
  107.     }
  108.  
  109.     WBMsg    != 0 {
  110.       Forbid( )
  111.       ReplyMsg( WBMsg )
  112.     }
  113.     
  114.     END
  115.  
  116. *--------------------------------------------------------------------------
  117.  
  118. * Console message routines
  119.  
  120. ;Writes a general copyright message and then a more specific message.
  121. ;Writes to standard output when run from CLI, and opens its own window
  122. ;when run from Workbench.
  123. ;    >= D0 = Msg-number
  124.  
  125. FHandle equr    d5
  126.  
  127. CONMsg    movem.l d0-d7/a0-a6,-(sp)
  128.     d4    = d0
  129.     d6    = 0
  130.     FHandle = Output( )
  131.     bne.s    1$
  132.     d6    = 1
  133.     lea    CONName(pc),a0
  134.     FHandle = Open( a0 #MODE_OLDFILE )
  135.     beq.s    exit
  136. 1$    moveq    #INFOMSG,d0
  137.     bsr.s    SendMsg
  138.     d0    = d4
  139.     bsr.s    SendMsg
  140.     d6    != 0 {
  141.       Delay( 127 )
  142.       Close( FHandle )
  143.     }
  144. exit    movem.l (sp)+,d0-d7/a0-a6
  145.     rts
  146.  
  147. *-------------
  148.  
  149. ;    >=    d0 = Msg-number
  150.  
  151. SendMsg neg.l    d0
  152.     d0    << 1
  153.     lea    CONMsgTable(pc),a0
  154.     a0    += 0(a0,d0.l) w
  155.     d2    = a0 
  156.     d3    = -1
  157. 1$    d3    ++
  158.     (a0)+    != 0 b
  159.     bne.s    1$
  160.     Write( FHandle * * )
  161.     rts
  162.  
  163. INFOMSG        =    0
  164. INSTALLED    =    -1
  165. REMOVED        =    -2
  166. CANTINSTALL    =    -3
  167. CANTREMOVE    =    -4
  168.  
  169. CONText        MACRO
  170.         dc.w        \1-CONMsgTable
  171.         ENDM
  172. CONMsgTable    CONText        Msg
  173.         CONText        Msg1
  174.         CONText        Msg2
  175.         CONText        Msg3
  176.         CONText        Msg4
  177.  
  178. CONName        dc.b        'CON:100/60/330/63/MenuStay',0
  179. Msg        dc.b        10,$9B,'0;33m MenuStay V1.0 '
  180.         dc.b        $9B,'0;31mis FreeWare',10
  181.         dc.b        ' 1993 by ',$9B,'0;33mAlexandros Loghis'
  182.         dc.b        $9B,'0;31m',10,' ',0
  183. Msg1        dc.b        'has now been installed...',10,0
  184. Msg2        dc.b        'has now been removed...',10,0
  185. Msg3        dc.b        "Error: Can't install handler",10,0
  186. Msg4        dc.b        "Error: Can't remove handler",10,0
  187.         even
  188.  
  189. *--------------------------------------------------------------------------
  190.  
  191. * Inputhandler removal and installation routines
  192.  
  193. ; This is general-purpose inputhandler removal-routine
  194. ; It only needs an ihs with a port-name to remove the handler
  195.  
  196. ;    >= a0 = ihs
  197. ;    >= a1 = first ihs-installation-routine or NULL
  198. ;    >= a2 = second ihs-installation-routine or NULL
  199. ;    => d0 = 0 means succes
  200.  
  201. rtsValue    equr        d7
  202.  
  203. RemoveHandler
  204.     movem.l d1/rtsValue/a0-a3/a6,-(sp)
  205.     moveq    #-1,rtsValue            weil EZAsm über d7 opt. will
  206.     a3    = a2
  207.     a2    = a0        
  208.     d1    = a1
  209.     beq.s    1$
  210.     jsr    (a1)        ; a0 = ihs
  211.     beq.s    2$
  212.     a2    = d0
  213. 1$    a0    = a2
  214.     d0    = #IND_REMHANDLER
  215.     bsr.s    TellInputDevice
  216.     rtsValue = d0
  217.     bne.s    2$
  218.     RemPort( &ihs_Port(A2) )
  219.     d0    = 0
  220.     bra.s    3$
  221. 2$    d0    = -1
  222. 3$    d1    = a3
  223.     beq.s    4$
  224.     a0    = a2
  225.     jsr    (a3)        ; a0 = ihs, d0 = 0 means succes
  226. 4$    d0    = rtsValue
  227.     movem.l (sp)+,d1/rtsValue/a0-a3/a6
  228.     rts
  229.  
  230. *-------------
  231.  
  232. ; This is general-purpose inputhandler installation-routine
  233. ; It only needs an ihs with a port-name to install the handler
  234.  
  235. ;    >= a0 = ihs
  236. ;    >= a1 = first ihs-installation-routine or NULL
  237. ;    >= a2 = second ihs-installation-routine or NULL
  238. ;    => d0 = 0 means succes
  239.  
  240. InstallHandler
  241.     movem.l d1/rtsValue/a0-a3/a6,-(sp)
  242.     moveq    #-1,rtsValue        else EZAsm will optimize using d7
  243.     a3    = a2
  244.     a2    = a0
  245.     d1    = a1
  246.     beq.s    1$
  247.     jsr    (a1)        ; a0 = ihs
  248.     beq.s    2$
  249.     a2    = d0
  250. 1$    a0    = a2
  251.     d0    = #IND_ADDHANDLER
  252.     bsr.s    TellInputDevice
  253.     rtsValue = d0 l
  254.     bne.s    2$
  255.     lea    ihs_Port(a2),a1
  256.     MP+LN_NAME(A1) = ihs_PortName(A2) l  ;MsgPort->mp_Node.ln_Name=Name
  257.     MP+LN_PRI(A1)  = 0 b             ;MsgPort->mp_Node.ln_Pri = 0
  258.     MP+LN_TYPE(A1) = #NT_MSGPORT b     ;MsgPort->mp_Node.ln_Type=NT_MSGPORT
  259.     MP_FLAGS(A1)   = #PA_IGNORE b     ;MsgPort->mp_Flags = PA_IGNORE
  260.     AddPort( * )
  261.     d0    = 0
  262.     bra.s    3$
  263. 2$    d0    = -1
  264. 3$    d1    = a3
  265.     beq.s    4$
  266.     a0    = a2
  267.     jsr    (a3)        ; a0 = ihs, d0 = 0 means succes
  268. 4$    d0    = rtsValue
  269.     movem.l (sp)+,D1/rtsValue/A0-A3/A6
  270.     rts
  271.  
  272. *-------------
  273.  
  274. ; Open the input device. Set up the I/O block to add or remove the
  275. ; input handler, and send the request to the input device. Finally,
  276. ; close the device
  277.  
  278. ;    >= a0 = ihs
  279. ;    >= d0 = Function to perform (IND_ADDHANDLER/IND_REMHANDLER)
  280. ;    => d0 = 0 means succes
  281.  
  282. Size    =    IOSTD_SIZE+MP_SIZE
  283. IReq    =    -IOSTD_SIZE
  284. IPort    =    -MP_SIZE-IOSTD_SIZE
  285.  
  286. TellInputDevice
  287.     link    a5,#-Size    until unlk use of EZAsm variables not allowed
  288.     movem.l d0/a5,-(sp)
  289.     d0    = #Size-1 w
  290. 1$    -(a5)    = 0 b
  291.     dbra    d0,1$
  292.     movem.l (sp)+,d0/a5
  293.  
  294.     movem.l d1-d2/rtsValue/a0-a3/a6,-(sp)
  295.     moveq    #-1,rtsValue        else EZAsm will optimize using d7
  296.     d2    = d0
  297.     a2    = a0
  298.     lea    IPort(a5),a3
  299.     MP+LN_TYPE(a3) = #NT_MSGPORT b    ; mp_Node.ln_Type=NT_MSGPORT;
  300.     MP_FLAGS(a3)   = #PA_SIGNAL b    ; mp_Flags    =PA_SIGNAL;
  301.     AllocSignal( -1 )
  302.     MP_SIGBIT(a3)  = d0 b        ; mp_SigBit    =MPSigBit;
  303.     bmi.s    exit2
  304.     FindTask( 0 )
  305.     MP_SIGTASK(a3) = d0 l        ; mp_SigTask    =FindTask(0);
  306.     lea    MP_MSGLIST(a3),a0
  307.     NEWLIST a0
  308.     lea    IReq(a5),a1
  309.     ; ExtReq->io_Message.mn_ReplyPort=taskReplyPort;
  310.     IO+MN_REPLYPORT(a1) = a3 l
  311.     ; ExtReq->io_Message.mn_Node.ln_Type=NT_MESSAGE;
  312.     IO+MN+LN_TYPE(a1)   = #NT_MESSAGE b
  313.     OpenDevice( &InputName(pc) 0 * 0 )
  314.     D0    = 0 w {            ; flag: error if > 0
  315.       lea    IReq(a5),a1
  316.       IO_COMMAND(a1) = d2 w
  317.       lea    ihs_Interrupt(a2),a0
  318.       IO_DATA(a1)     = a0 l
  319.       rtsValue     = DoIO( * )
  320.       CloseDevice( &IReq(a5) )
  321.     }
  322.     d0    = MP_SIGBIT(a3) b
  323.     FreeSignal( * )
  324. exit2    d0    = rtsValue
  325.     movem.l (sp)+,d1-d2/rtsValue/a0-a3/a6
  326.     unlk    a5
  327.     rts
  328.  
  329. *-------------
  330.  
  331. ; Each handler should have such a pair of installation-routines.
  332. ; The first one is passed to InstallHandler in A1, and it
  333. ; is called immediately when entering InstallHandler.
  334. ; The second one is passed to InstallHandler in A2, and it
  335. ; is called if installation of handler and message-port succeeds.
  336.  
  337. ;    >= a0 = ihs
  338. ;    => d0    has to point to ihs to be used when installation proceeds.
  339. ;        If d0 = 0 then installation is aborted.
  340.  
  341. PSPrepIHS1
  342.     movem.l d1/a0-a1/a6,-(sp)
  343.     HMem    = AllocMem( #HandlerSize #MEMF_PUBLIC|MEMF_CLEAR )
  344.     beq.s    2$
  345.     a1    = d0
  346.     lea    IHS(pc),a0
  347.     d0    = #HandlerSize
  348.     movem.l d0/a0-a1,-(sp)
  349.     CopyMem( * * * )
  350.     movem.l (sp)+,d0/a0-a1
  351.     ihs_Length(a1) = d0 l    ; This will enable removal by other programs
  352.     lea    HandlerCode-IHS(a1),a0
  353.     ihs_Interrupt+IS_CODE(a1) = a0     ; ihs_Interrupt.is_Code = Handler
  354.     ihs_Interrupt+IS_DATA(a1) = 0 l     ; ihs_Interrupt.is_Data = 0
  355.     lea    IHSName-IHS(a1),a0
  356.     ihs_PortName(A1)      = a0 l ; ihs_PortName         = IHSName
  357.     ; ihs_Interrupt.is_Node.ln_Pri = HPRI
  358.     ihs_Interrupt+LN_PRI(a1)       = #HPRI b
  359.     d0    = a1
  360. 2$    movem.l (sp)+,d1/a0-a1/a6
  361.     rts
  362.  
  363. *-------------
  364.  
  365. ;    >= a0 = ihs
  366. ;    => d0 = 0 means everything went perfect
  367. ;        -1 means something went wrong during installation
  368.  
  369. PSPrepIHS2
  370.     movem.l d0-d1/a0-a1/a6,-(sp)
  371.     d0    != 0 {
  372.       d0    != HMem {
  373.         FreeMem( d0 #HandlerSize )
  374.       }
  375.     }
  376.     movem.l (sp)+,d0-d1/a0-a1/a6
  377.     rts
  378.  
  379. *-------------
  380.  
  381. ; Each handler should have such a pair of ending-routines.
  382. ; The first one is passed to RemoveHandler in A1, and it
  383. ; is called immediately when entering RemoveHandler.
  384. ; The second one is passed to RemoveHandler in A2, and it
  385. ; is called if removal of handler and message-port succeeds.
  386.  
  387. ;    >= a0 = ihs
  388. ;    => d0    has to point to ihs to be used when removal proceeds
  389. ;        If D0 = 0 then removal is aborted
  390.  
  391. PSEndIHS1
  392.     -(sp)    = a1
  393.     lea    IHSName(pc),a1
  394.     bsr.s    FindThisPort
  395.     a1    = (sp)+
  396.     rts
  397.  
  398. *-------------
  399.  
  400. ;    >= a0 = ihs
  401. ;    => d0 = 0 means everything went perfect
  402. ;        -1 means something went wrong during removal
  403.  
  404. PSEndIHS2
  405.     movem.l d0-d1/a0-a1/a6,-(sp)
  406.     d0    >= 0 {
  407.       FreeMem( a0 ihs_Length(a0) )
  408.     }
  409.     movem.l (sp)+,d0-d1/a0-a1/a6
  410.     rts
  411.  
  412. *-------------
  413.  
  414. ;    >= a1 = Portname
  415. ;    => d0 = Port or NULL (cc reflects result also)
  416.  
  417. FindThisPort
  418.     movem.l d1-d2/a0-a1/a6,-(sp)
  419.     d2    = a1
  420.     Forbid( )
  421.     d2    = FindPort( d2 )
  422.     Permit( )
  423.     d0    = d2
  424.     movem.l (sp)+,d1-d2/a0-a1/a6
  425.     rts
  426.  
  427.  
  428. *--------------------------------------------------------------------------
  429.  
  430. * Input-handler start
  431.  
  432. ihs_Port    =    0
  433. ihs_Interrupt    =    MP_SIZE
  434. ihs_ID        =    MP_SIZE+IS_SIZE
  435. ihs_Length    =    MP_SIZE+IS_SIZE+4
  436. ihs_Flags    =    MP_SIZE+IS_SIZE+8
  437. ihs_PortName    =    MP_SIZE+IS_SIZE+10
  438. ihs_LocalArea    =    MP_SIZE+IS_SIZE+14
  439. ihs_SIZE    =    MP_SIZE+IS_SIZE+14
  440.  
  441. ihs_Start MACRO
  442.         dcb.b        MP_SIZE,0    ; Message-Port structure
  443.         dcb.b        IS_SIZE,0    ; Interrupt structure
  444.         dc.l        'P_IH'        ; ID
  445.         dc.l        0        ; Length of handler 
  446.         dc.w        0        ; Flags
  447.         dc.l        0
  448.       ENDM
  449.  
  450. HPRI        =    55
  451. HDisabled    =    0
  452. HNoExtRemoval    =    1
  453.  
  454. ; This is the handler-block
  455. IHS    ihs_Start
  456.  
  457. ; Put local data here
  458. IfBlanker    dc.b    0    must be before IfRMBDown !
  459. IfRMBDown    dc.b    0    must be after  IfBlanker !
  460. IntBase        dc.l    0
  461. RawKeyBuffer    dcb.w    5,0    last 5 pressed keys
  462. RKBLastElem    = *-2
  463.  
  464. ; IHS name
  465. IHSName dc.b        'MenuStay V1.0 Port',0
  466.     even
  467.  
  468.  
  469. ; For each event in the event list:
  470. ; If we were waiting for this event then signal the task.
  471. ; When all the events have been checked, return the event list so that
  472. ; others can do their things.
  473.  
  474. Next    =    ie_NextEvent
  475. Class    =    ie_Class
  476. Code    =    ie_Code
  477. Qual    =    ie_Qualifier
  478.  
  479. EList    equr    a0
  480. Event    equr    a1
  481.  
  482. Tmp    equr    a2
  483. BPtr    equr    a3        Raw key buffer pointer
  484. WPtr    equr    a3        Active window pointer
  485. Dma    equr    a4
  486. IfB    equr    a5        Ptr to IfBlanker
  487. IfRD    equr    a5        IfRMBDown
  488.  
  489. RegLst    reg    Event/EList/Tmp/BPtr/Dma/IfB/d1
  490.  
  491. *-------------
  492.  
  493. TstHPos tst.b    vhposr-dmacon(Dma)
  494.     bne.s    TstHPos
  495.     btst    #0,vposr+1-dmacon(Dma)
  496.     bne.s    TstHPos
  497.     rts
  498.  
  499. *-------------
  500.  
  501. * Change these constants to activate the blanker with an other key combination
  502.  
  503. Key1Up    equ    $cc        Raw key code from cursor up when released 
  504. Key1Dn    equ    $4c            "        "     pressed
  505. Key2Up    equ    $cd        Raw key code from cursor down when released 
  506. Key2Dn    equ    $4d            "        "       pressed
  507.  
  508. TstUp    cmp.w    #Key1Up,-(BPtr)
  509.     beq.s    1$
  510.     cmp.w    #Key2Up,(BPtr)
  511. 1$    rts
  512. TstDwn    subq.l    #2,BPtr
  513. TstDwn2 cmp.w    #Key1Dn,(BPtr)
  514.     beq.s    1$
  515.     cmp.w    #Key2Dn,(BPtr)
  516. 1$    rts
  517.  
  518. *-------------
  519.  
  520. TstBlanker
  521.     (IfB)    != 0 {
  522.       bsr.s TstHPos
  523.       (Dma) = #DMAF_SETCLR|DMAF_COPPER|DMAF_RASTER w
  524.       (IfB) -- b
  525.     }
  526.     rts
  527.  
  528. *-------------
  529.  
  530. ;    >= a0 = List of InputEvents
  531. ;    >= a1 = HandlerData
  532.  
  533. HandlerCode
  534.     movem.l RegLst,-(sp)
  535.     Event    = EList l
  536. ieLoop    d0    = Event
  537.     beq    NoMoreEvents
  538.  
  539.     lea    $dff000+dmacon,Dma
  540.     lea    IfBlanker(pc),IfB
  541.  
  542.     cmpi.b    #IECLASS_RAWKEY,Class(Event)
  543.     bne.s    NxtTst
  544.     bsr.s    TstBlanker
  545.     d0    = Code(Event) w
  546.     cmp.w    RKBLastElem(pc),d0    still pressing the same key ?
  547.     beq.s    NxtTst            yes
  548.     lea    RawKeyBuffer(pc),BPtr              prepare
  549.     lea    RawKeyBuffer+2(pc),Tmp              to
  550.     d0    = #(RKBLastElem-RawKeyBuffer-1)/2    ; shift
  551. 1$    (BPtr)+ = (Tmp)+ w                ; the
  552.     dbra    d0,1$                    ; RawKeyBuffer
  553.     (BPtr)+ = Code(Event) w                ; enter actual key
  554.  
  555.     bsr.s    TstUp        test if the 2 key where pressed
  556.     bne.s    NxtTst
  557.     bsr.s    TstUp
  558.     beq.s    2$
  559.     bsr.s    TstDwn2
  560.     bne.s    NxtTst
  561.     bsr.s    TstUp        and then if there where released
  562.     bne.s    NxtTst
  563. 2$    bsr.s    TstDwn
  564.     bne.s    NxtTst
  565.     bsr.s    TstDwn
  566.     bne.s    NxtTst
  567.  
  568.     bsr    TstHPos                  wait until start of raster
  569.     (Dma)    = #DMAF_COPPER|DMAF_RASTER w    ; screen
  570.     color-dmacon(Dma) = 0 w            ; and
  571.     spr+4-dmacon(Dma) = 0 l            ; mouse blanking
  572.     (IfB)    ++ b                ; set flag to true
  573. NxtTst
  574.  
  575.     cmpi.b    #IECLASS_RAWMOUSE,Class(Event)
  576.     bne.s    NxtEv
  577.     bsr.s    TstBlanker
  578.     IfRD    ++ l                ; IfB is from now tabu
  579.     cmpi.w    #IECODE_LBUTTON,Code(Event)
  580.     beq.s    PressLMB
  581.     cmpi.w    #IECODE_RBUTTON,Code(Event)
  582.     beq.s    PressRMB
  583.     cmpi.w    #IECODE_UP_PREFIX|IECODE_RBUTTON,Code(Event)
  584.     bne.s    NxtEv
  585. ReleaseRMB
  586.     tst.b    (IfRD)
  587.     beq.s    NxtEv
  588.     bsr.s    TstMenuBar
  589.     bcs.s    DontRemove
  590.     bra.s    clear
  591. PressRMB
  592.     (IfRD)    = 0 {
  593.       bsr.s     TstMenuBar
  594.       bcc.s     NxtEv
  595.       (IfRD) ++ b
  596.       bra.s     NxtEv
  597.     }
  598. clear    (IfRD)    = 0
  599. DontRemove
  600.     (IfRD)    != 0 {
  601.       Class(Event) = 0 w    ; Kill event (make it an IECLASS_NULL event)
  602.       (IfRD) ++ b        ; (IfRD) = 2 = staymode on
  603.     }
  604. NxtEv    Event    = Next(Event) l ; Just move on to next Event
  605.     bra    ieLoop
  606.  
  607. NoMoreEvents
  608.     d0    = EList
  609.     movem.l (sp)+,RegLst
  610.     rts
  611.  
  612. *-------------
  613.  
  614. TstMenuBar
  615.     Tmp    = IntBase(pc) l
  616.     WPtr    = ib_ActiveWindow(Tmp) l
  617.     wd_MenuStrip(WPtr) != 0 l {    ; if exists
  618.       Tmp    = ib_ActiveScreen(Tmp) l
  619.       d0    = sc_MouseY(Tmp) w
  620.       d0    < #$100 w {
  621.         d0    < sc_BarHeight(Tmp) b
  622.       }
  623.     }
  624.     rts            ; carry flag = 1 means MousePtr in menubar
  625.  
  626. *-------------
  627.  
  628. CHARNR    equ    256            array length
  629.  
  630. lft    equr    d0        left border
  631. rght    equr    d1        right    "
  632.  
  633. Mn    equr    a2
  634. Item    equr    a3
  635. HiIt    equr    a4        Highlighted item
  636. Base    equr    a5        Base address from array of ASCII codes
  637.  
  638. PressLMB
  639.     cmp.b    #2,(IfRD)    ; (IfRD) = 2 = staymode on
  640.     bne.s    NxtEv
  641.  
  642.     Base    = sp l
  643.     lea    -CHARNR(sp),sp
  644.     d0    = #(CHARNR/4)-1
  645. 1$    -(Base) = 0 l        ; clear array
  646.     dbra    d0,1$          Base = sp
  647.  
  648.     Tmp    = IntBase(pc) l
  649.     Tmp    = ib_ActiveWindow(Tmp) l
  650.     Mn    = wd_MenuStrip(Tmp) l
  651.     sub.l    HiIt,HiIt
  652.  
  653. Menus    d0    = mu_FirstItem(Mn) l
  654.     beq.s    noItems
  655.     bsr.s    RekSrch
  656. noItems Mn    = mu_NextMenu(Mn) l
  657.     d0    = Mn
  658.     bne.s    Menus
  659.  
  660.     d0    = HiIt        ; any item  highlighted ?
  661.     beq.s    exit3          no
  662.     tst.b    mi_Command(HiIt)  command already exists ?
  663.     bne.s    exit3          yes
  664.  
  665.     moveq    #'Z'-'A',rght          = 25
  666. bigEQsm 'A'(Base,rght.w) != 0 b {    ; big letters command = small
  667.       'a'(Base,rght.w) ++ b        ;            letters com.
  668.     }
  669.     'A'(Base,rght.w) ++ b        ; don't use big letters commands
  670.     rght    -- b
  671.     bpl.s    bigEQsm              until negative
  672.     
  673.     moveq    #'a',lft    small
  674.     moveq    #'z',rght    letters
  675.     bsr.s    ChrSrch
  676.     beq.s    found
  677.  
  678.     moveq    #'0',lft    numbers
  679.     moveq    #'9',rght
  680.     bsr.s    ChrSrch
  681.     beq.s    found
  682.  
  683.     moveq    #'!',lft    all printable
  684.     moveq    #'~',rght    chars
  685.     bsr.s    ChrSrch
  686.     bne.s    exit3        not found
  687.  
  688. found    mi_Command(HiIt) = lft b        ; set command
  689.     or.w    #COMMSEQ,mi_Flags(HiIt)          set command flag
  690.     Class(Event) = 0 w    ; Kill event (make it an IECLASS_NULL event)
  691.  
  692. exit3    lea    CHARNR(sp),sp
  693.     bra    NxtEv
  694.  
  695. *-------------
  696.  
  697. RekSrch                    ; rekursive searching throught items
  698.     Item    = d0
  699.     d0    = mi_Flags(Item) w
  700.     d0    &= #HIGHITEM w        ; Test if item currently highlighted
  701.     beq.s    1$              no
  702.     HiIt    = Item l
  703.     d0    = 0
  704. 1$    d0    = mi_Command(Item) b    ; get char
  705.     0(Base,d0.w) ++ b        ; mark it in the array
  706.     d0    = mi_SubItem(Item)
  707.     beq.s    noSubIt
  708.     -(sp)    = Item l
  709.     bsr.s    RekSrch
  710.     Item    = (sp)+ l
  711. noSubIt d0    = mi_NextItem(Item)
  712.     bne.s    RekSrch
  713.     rts
  714.  
  715. *-------------
  716.  
  717. ChrSrch        ; search for the first unused char that is >= lft & <= rght
  718.     0(Base,lft.w) != 0 b {
  719.       lft    ++ b
  720.       cmp.b rght,lft
  721.       bls.s ChrSrch
  722.     }
  723.     rts        ; zero flag = 1 then a char was found
  724.  
  725. *-------------
  726.  
  727. HandlerSize    =    *-IHS
  728.  
  729. *--------------------------------------------------------------------------
  730.  
  731. DosName        dc.b    "dos.library",0
  732.     even
  733. InputName    dc.b    "input.device",0
  734.     even
  735. IntName        dc.b    "intuition.library",0
  736.     even
  737.